package com.bfsoft.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bfsoft.springbootinit.mapper.SysUserMapper;
import com.bfsoft.springbootinit.pojo.dto.IdDTO;
import com.bfsoft.springbootinit.pojo.dto.sysuser.AdminUserDetailDTO;
import com.bfsoft.springbootinit.pojo.dto.sysuser.AdminUserPageDTO;
import com.bfsoft.springbootinit.pojo.entity.*;
import com.bfsoft.springbootinit.pojo.vo.ResultVO;
import com.bfsoft.springbootinit.pojo.vo.sysuser.AdminUserVO;
import com.bfsoft.springbootinit.service.*;
import com.bfsoft.springbootinit.util.DESUtil;
import com.bfsoft.springbootinit.util.MD5Util;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * (用户表)SYS_USER 服务实现类
 * </p>
 *
 * @author xxx
 * @since 2024-10-18
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private ISysUserRoleService sysUserRoleService;
    @Resource
    private ISysRoleService sysRoleService;
    @Resource
    private ISysRoleFunctionService sysRoleFunctionService;

    private final String SALT="biekanwozhishiyizhiyang";

    @Override
    public ResultVO<Page<AdminUserVO>> getAdminList(AdminUserPageDTO dto) {
        Page<SysUser> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(dto.getRoleId())){
            List<SysUserRole> sysUserRoles = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getRId, dto.getRoleId()));
            if (!sysUserRoles.isEmpty()){
                wrapper.in(SysUser::getId, sysUserRoles.stream().map(SysUserRole::getUId).collect(Collectors.toList()));
            }else {
                return ResultVO.ok(null);
            }
        }
        Page<SysUser> userPage = page(page, wrapper
                .eq(StringUtils.isNotBlank(dto.getCompanyId()), SysUser::getCompanyId, dto.getCompanyId())
                .eq(StringUtils.isNotBlank(dto.getBaseId()), SysUser::getBaseId, dto.getBaseId())
                .like(StringUtils.isNotBlank(dto.getUserAccountName()), SysUser::getUserAccountName, dto.getUserAccountName())
                .like(StringUtils.isNotBlank(dto.getUserName()), SysUser::getUserName, dto.getUserName()));
        Page<AdminUserVO> sysUserPage = new Page<>();
        BeanUtils.copyProperties(userPage, sysUserPage);
        List<AdminUserVO> adminUserVOS = new ArrayList<>();
        userPage.getRecords().forEach(i -> {
            AdminUserVO adminUserVO = new AdminUserVO();
            BeanUtils.copyProperties(i, adminUserVO);
            List<SysUserRole> sysUserRoles = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>()
                    .eq(SysUserRole::getUId, i.getId()));
            adminUserVO.setRoleName(sysRoleService.listByIds(sysUserRoles.stream().map(SysUserRole::getRId).collect(Collectors.toList())).stream().map(SysRole::getRoleName).collect(Collectors.joining("、")));
            adminUserVOS.add(adminUserVO);
        });
        sysUserPage.setRecords(adminUserVOS);
        return ResultVO.ok(sysUserPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVO<Object> saveOrUpdateAdmin(AdminUserDetailDTO dto) {
        SysUser sysUserOne = getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserAccountName, dto.getUserAccountName()));
        Set<String> functionIds = new HashSet<>();
        for (String roleId : dto.getRoleIds ()) {
            functionIds.addAll(sysRoleFunctionService.list(new LambdaQueryWrapper<SysRoleFunction>().eq(SysRoleFunction::getRId, roleId)).stream().map(SysRoleFunction::getFId).collect(Collectors.toList()));
        }


        if (dto.getId() == null && sysUserOne != null) {
            return ResultVO.fail(null, "账号已存在，请重新输入！");
        }
        if (!dto.getPassword().equals(dto.getPasswordAgain())) {
            return ResultVO.fail(null, "两次输入的密码不一致，请重新输入！");
        }
        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(dto, sysUser);
        try {
            sysUser.setPassword( MD5Util.MD5Encode(MD5Util.MD5Encode( DESUtil.decryptByDES(dto.getPassword())+SALT)));
        } catch (Exception e) {
            log.error("密码加密失败", e);
            throw new RuntimeException(e);
        }
        saveOrUpdate(sysUser);

        if (dto.getId() != null) {
            sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
                    .eq(SysUserRole::getUId, sysUser.getId()));
        }

        dto.getRoleIds().forEach(i -> {
            SysUserRole selectedRole = new SysUserRole();
            selectedRole.setRId(i);
            selectedRole.setUId(sysUser.getId());
            sysUserRoleService.save(selectedRole);
        });

        return ResultVO.ok(null, "操作成功");
    }

    @Override
    public ResultVO<Object> deleteAdmin(IdDTO dto) {
        sysUserMapper.deleteById(dto.getId());
        sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUId, dto.getId()));
        return ResultVO.ok(null, "删除成功");
    }

    @Override
    public ResultVO<AdminUserDetailDTO> getDetailAdmin(IdDTO dto) {
        SysUser sysUser = getById(dto.getId());
        AdminUserDetailDTO adminUserDetailDTO = new AdminUserDetailDTO();
        BeanUtils.copyProperties(sysUser, adminUserDetailDTO);
        adminUserDetailDTO.setPassword(null);
        List<SysUserRole> sysUserRoles = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUId, sysUser.getId()));
        adminUserDetailDTO.setRoleIds(sysUserRoles.stream().map(SysUserRole::getRId).collect(Collectors.toList()));
        return ResultVO.ok(adminUserDetailDTO);
    }
}
